package com.zxx.casserver.modules.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.zxx.cascommon.base.exception.DataNoChangeException;
import com.zxx.cascommon.base.exception.DataNotExistException;
import com.zxx.cascommon.base.exception.ParamsException;
import com.zxx.cascommon.base.utils.UUIDUtils;
import com.zxx.casserver.modules.app.entity.AppDO;
import com.zxx.casserver.modules.app.entity.AppVO;
import com.zxx.casserver.modules.app.mapper.AppMapper;
import com.zxx.casserver.modules.app.service.IAppService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

/**
 * 系统应用管理-服务实现类
 *
 * @author zhoukai
 * @since 2020-06-30
 */
@Service
public class AppServiceImpl extends ServiceImpl<AppMapper, AppDO> implements IAppService {

    @Override
    public IPage<AppDO> listApp(AppVO appVO) {
        Page<AppDO> page = new Page<>(appVO.getCurPage(), appVO.getPageSize());
        QueryWrapper<AppDO> queryWrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(appVO.getIds())) {
            queryWrapper.in("app_id", appVO.getIds());
        }
        if (!ObjectUtils.isEmpty(appVO.getAppId())) {
            queryWrapper.eq("app_id", appVO.getAppId());
        }
        if (!ObjectUtils.isEmpty(appVO.getName())) {
            queryWrapper.eq("name", appVO.getName());
        }
        if (!ObjectUtils.isEmpty(appVO.getType())) {
            queryWrapper.eq("type", appVO.getType());
        }
        if (!ObjectUtils.isEmpty(appVO.getUrl())) {
            queryWrapper.eq("url", appVO.getUrl());
        }
        if (!ObjectUtils.isEmpty(appVO.getTestUrl())) {
            queryWrapper.eq("test_url", appVO.getTestUrl());
        }
        if (!ObjectUtils.isEmpty(appVO.getRemark())) {
            queryWrapper.eq("remark", appVO.getRemark());
        }
        if (!ObjectUtils.isEmpty(appVO.getAppKey())) {
            queryWrapper.eq("app_key", appVO.getAppKey());
        }
        if (!ObjectUtils.isEmpty(appVO.getStartTime())) {
            queryWrapper.ge("create_time", appVO.getStartTime());
        }
        if (!ObjectUtils.isEmpty(appVO.getEndTime())) {
            queryWrapper.le("create_time", appVO.getEndTime());
        }
        if (!ObjectUtils.isEmpty(appVO.getColumns()) && !ObjectUtils.isEmpty(appVO.getAsc())) {
            String columnNames = Joiner.on(",").join(appVO.getColumns());
            if (appVO.getAsc()) {
                queryWrapper.orderByAsc(columnNames);
            } else {
                queryWrapper.orderByDesc(columnNames);
            }
        } else {
            queryWrapper.orderByDesc("create_time");
        }
        return page(page, queryWrapper);
    }

    @Override
    public AppDO saveApp(AppVO appVO) {
        //判断url、testUrl是否已经存在
        AppDO urlApp = getByUrl(appVO.getUrl());
        if (!ObjectUtils.isEmpty(urlApp)) {
            throw new ParamsException();
        }

        AppDO testUrlApp = getByTestUrl(appVO.getTestUrl());
        if (!ObjectUtils.isEmpty(testUrlApp)) {
            throw new ParamsException();
        }

        AppDO appDO = JSON.parseObject(JSON.toJSONString(appVO), AppDO.class);
        appDO.setCreateTime(System.currentTimeMillis());
        appDO.setUpdateTime(System.currentTimeMillis());

        //生成appKey和appSecret
        appDO.setAppKey(UUIDUtils.getUuid());
        appDO.setAppSecret(UUIDUtils.getUuid());

        boolean isSave = save(appDO);
        if (isSave) {
            return appDO;
        }
        return null;
    }

    /**
     * 根据url返回接口的
     *
     * @param url
     * @author zhoukai
     * @date 2020/8/14 17:33
     */
    private AppDO getByUrl(String url) {
        QueryWrapper<AppDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("url", url);
        return getOne(queryWrapper);
    }

    /**
     * 根据url返回接口的
     *
     * @param testUrl
     * @author zhoukai
     * @date 2020/8/14 17:33
     */
    private AppDO getByTestUrl(String testUrl) {
        QueryWrapper<AppDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("test_url", testUrl);
        return getOne(queryWrapper);
    }

    @Override
    public AppDO updateApp(AppVO appVO) {
        AppDO oldApp = getById(appVO.getAppId());
        if (ObjectUtils.isEmpty(oldApp)) {
            throw new DataNotExistException();
        }
        AppDO appDO = checkChange(appVO, oldApp);
        if (ObjectUtils.isEmpty(appDO)) {
            throw new DataNoChangeException();
        }

        //判断url、testUrl是否已经存在
        if (!ObjectUtils.isEmpty(appDO.getUrl())) {
            AppDO urlApp = getByUrl(appDO.getUrl());
            if (!ObjectUtils.isEmpty(urlApp)
                    && !appVO.getAppId().equals(urlApp.getAppId())) {
                throw new ParamsException();
            }
        }

        if (!ObjectUtils.isEmpty(appDO.getTestUrl())) {
            AppDO testUrlApp = getByTestUrl(appVO.getTestUrl());
            if (!ObjectUtils.isEmpty(testUrlApp)
                    && !appVO.getAppId().equals(testUrlApp.getAppId())) {
                throw new ParamsException();
            }
        }

        boolean isUpdate = updateById(appDO);
        if (isUpdate) {
            return appDO;
        }
        return null;
    }

    @Override
    public AppDO removeApp(AppVO appVO) {
        AppDO oldApp = getById(appVO.getAppId());
        if (ObjectUtils.isEmpty(oldApp)) {
            throw new DataNotExistException();
        }
        boolean isDelete = removeById(appVO.getAppId());
        if (isDelete) {
            return oldApp;
        }
        return null;
    }

    /**
     * 根据传入的应用相关信息与数据库旧数据进行比较
     *
     * @return 返回有更新信息的应用对象，没有则返回null
     * @author zhoukai
     * @date 2020/7/31 16:56
     */
    private AppDO checkChange(AppVO appVO, AppDO oldApp) {
        AppDO appDO = new AppDO();
        appDO.setAppId(appVO.getAppId());
        appDO.setUpdateTime(System.currentTimeMillis());

        boolean isChange = false;

        if (!ObjectUtils.isEmpty(appVO.getName()) && !appVO.getName().equals(oldApp.getName())) {
            appDO.setName(oldApp.getName());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(appVO.getUrl()) && !appVO.getUrl().equals(oldApp.getUrl())) {
            appDO.setUrl(oldApp.getUrl());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(appVO.getTestUrl()) && !appVO.getTestUrl().equals(oldApp.getTestUrl())) {
            appDO.setTestUrl(oldApp.getTestUrl());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(appVO.getType()) && !appVO.getType().equals(oldApp.getType())) {
            appDO.setType(oldApp.getType());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(appVO.getIcon()) && !appVO.getIcon().equals(oldApp.getIcon())) {
            appDO.setIcon(oldApp.getIcon());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(appVO.getRemark()) && !appVO.getRemark().equals(oldApp.getRemark())) {
            appDO.setRemark(oldApp.getRemark());
            isChange = true;
        }

        return isChange ? appDO : null;
    }
}
